package mx.itesm.gda.clever.ui;

import java.io.ByteArrayInputStream;
import java.util.Enumeration;
import java.util.List;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import cml.analyzing.Analyzer;
import cml.analyzing.SymTable;
import cml.analyzing.Symbol;
import cml.parsing.ParsingScanner;
import cml.parsing.parser;
import cml.scanning.Scanner;

public class SymbolTableView extends ViewPart implements SelectionListener {
	
	public static final String ID = "mx.itesm.gda.clever.ui.SymbolTableView";
	
	private Combo combo;
	
	private Table table;
	
	private List<SymTable> tables;
	
	private String[] columnHeaders = {
			LocalizedMessages.SymbolTableView_symbolHeader,
			LocalizedMessages.SymbolTableView_typeHeader,
			LocalizedMessages.SymbolTableView_lineHeader
	};
	private int[] columnStyles = {
			SWT.LEFT, SWT.LEFT, SWT.RIGHT
	};
	private int[] columnWidths = {
			125, 75, 25
	};
	
	@Override
	public void createPartControl(final Composite parent) {
		
		// Set up combo box.
		
		final GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.makeColumnsEqualWidth = true;
		parent.setLayout(layout);
		
		combo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY);
		combo.addSelectionListener(this);
		
		GridData data = new GridData();
		data.grabExcessHorizontalSpace = true;
		data.horizontalAlignment = GridData.FILL;
		combo.setLayoutData(data);
		
		// Set up table.
		
		table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
				| SWT.FULL_SELECTION);
		table.setLinesVisible(true);
		table.setHeaderVisible(true);
		
		for (int i = 0; i < columnHeaders.length; i++) {
			final TableColumn column = new TableColumn(table, columnStyles[i]);
			column.setText(columnHeaders[i]);
			column.setWidth(columnWidths[i]);
		}
		
		data = new GridData();
		data.grabExcessVerticalSpace = true;
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.FILL;
		table.setLayoutData(data);
	}
	
	public void analyze(final ITextEditor editor) throws Exception {
		final IDocumentProvider provider = editor.getDocumentProvider();
		if (provider == null) return;
		
		final IDocument document = provider.getDocument(editor.getEditorInput());
		final String text = document.get();
		
		final Scanner scanner = new Scanner(new ByteArrayInputStream(text
				.getBytes()));
		final ParsingScanner ps = new ParsingScanner(scanner);
		final parser p = new parser(ps);
		
		p.parse();
		ErrorsView.setErrors(p.getSynErrors(), true);
		
		Analyzer sem = new Analyzer();
		sem.analyze(p.getTree());
		
		ErrorsView.addErrors(sem.getSemErr(), false);
		
		tables = sem.getTables();
		combo.removeAll();
		for (int i = 0; i < tables.size(); i++) {
			combo.add(tables.get(i).getName());
		}
		table.removeAll();
		if (!tables.isEmpty()) {
			combo.select(0);
			widgetSelected(null);
		}
	}
	
	@Override
	public void setFocus() {
		table.setFocus();
	}
	
	@Override
	public void widgetSelected(final SelectionEvent event) {
		table.removeAll();
		final SymTable t = tables.get(combo.getSelectionIndex());
		
		for (Enumeration<String> e = t.names(); e.hasMoreElements(); ) {
			final String name = e.nextElement();
			final Symbol symbol = t.getSymbol(name);
			
			final TableItem item = new TableItem(table, SWT.NONE);
			item.setText(0, symbol.getName());
			item.setText(1, symbol.getType().toString());
			item.setText(2, Integer.toString(symbol.getLineNo() + 1));
		}
	}
	
	@Override
	public void widgetDefaultSelected(final SelectionEvent event) {}
	
}
